class Tile3d extends Cesium.Cesium3DTileset {
	constructor(options) {
		super(options.model)
		this._model = options.model;
		this._attributes = options.attributes;
		this.init();
	}
	init(){
		let _this=this;
		_this.readyPromise.then(function(tileset) {
			if(_this._model.location && Cesium.defined(_this._model.location.x) && Cesium.defined(_this._model.location.y) ){
				_this.setMatrix();
			}else{
				_this.heightOffset=Cesium.defaultValue(_this._model.heightOffset,0);
				let center=_this.getCenter(tileset);
				if (Cesium.defined(center)){
					if (!Cesium.defined(_this._model.location)){
						_this._model.location={}
					}
					if (!Cesium.defined(_this._model.rotation)){
						_this._model.rotation={}
					}
					_this._model.location.x=Cesium.defaultValue(center.x,0);
					_this._model.location.y=Cesium.defaultValue(center.y,0)
					_this._model.location.z=Cesium.defaultValue(center.z, 0)
					_this._model.rotation.pitch=Cesium.defaultValue(center.rotation_x,0);
					_this._model.rotation.heading=Cesium.defaultValue(center.rotation_y,0)
					_this._model.rotation.roll=Cesium.defaultValue(center.rotation_z, 0)
				}
			}
			if(_this.readyLoad){
				_this.readyLoad(tileset);
			}
		});
	}
	set id(id){
		this._model.id = id;
	}
	get id(){
		return this._model.id;
	}
	set model(model) {
		this._model = model;
	}
	get model() {
		return this._model;
	}
	set attributes(attributes) {
		this._attributes= attributes;
	}
	get attributes() {
		return this._attributes;
	}
	setAttribute(key, value) {
		this._attributes[key]=value;
	}
	removeAttribute(key) {
		if (Cesium.defined(this._attributes[key])) {
			delete this._attributes[key]
		}
	}
	addEventListener(type,fn){
		if('readyLoad'==type){
			this.readyLoad=fn;
		}
	}
	set heightOffset(heightOffset){
		this._heightOffset= Cesium.defaultValue(heightOffset,0);
		var boundingSphere = this.boundingSphere;
		var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
		var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
		var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, this._heightOffset);
		var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
		this.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
	}
	get heightOffset(){
		return this._heightOffset;
	}
	get location(){
		return this._model.location;
	}
	set location(location){
		if(Cesium.defined(location.x)){
			this._model.location.x=location.x;
		}
		if(Cesium.defined(location.y)){
			this._model.location.y=location.y;
		}
		if(Cesium.defined(location.z)){
			this._model.location.z=location.z;
		}
		setMatrix();
	}
	get rotation(){
		return this._model.rotation;
	}
	set rotation(rotation){
		if(Cesium.defined(rotation.heading)){
			this._model.rotation.heading=rotation.heading;
		}
		if(Cesium.defined(rotation.pitch)){
			this._model.rotation.pitch=rotation.pitch;
		}
		if(Cesium.defined(rotation.roll)){
			this._model.rotation.roll=rotation.roll;
		}
		setMatrix();
	}
	setMatrix(){
	   var transformPosition =Cesium.Cartesian3.fromDegrees(this._model.location.x*1, this._model.location.y*1,this._model.location.z*1);
	   var matrix = Cesium.Transforms.eastNorthUpToFixedFrame(transformPosition);
	   var scale = Cesium.Matrix4.fromUniformScale(Cesium.defaultValue(this._model.scale,0));
	   Cesium.Matrix4.multiply(matrix, scale, matrix);
	   var rotationX = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(Cesium.defaultValue(this._model.rotation.pitch,0)));
	   var rotationY = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(Cesium.defaultValue(this._model.rotation.heading,0)));
	   var rotationZ = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(Cesium.defaultValue(this._model.rotation.roll,0)));
	   var rotationTranslationX = Cesium.Matrix4.fromRotationTranslation(rotationX);
	   var rotationTranslationY = Cesium.Matrix4.fromRotationTranslation(rotationY);
	   var rotationTranslationZ = Cesium.Matrix4.fromRotationTranslation(rotationZ);
	   Cesium.Matrix4.multiply(matrix, rotationTranslationX, matrix);
	   Cesium.Matrix4.multiply(matrix, rotationTranslationY, matrix);
	   Cesium.Matrix4.multiply(matrix, rotationTranslationZ, matrix);
	   this._root.transform=matrix;
	}
	getMatrix(){
	   var transformPosition =Cesium.Cartesian3.fromDegrees(this._model.location.x*1, this._model.location.y*1,this._model.location.z*1);
	   var matrix = Cesium.Transforms.eastNorthUpToFixedFrame(transformPosition);
	   var scale = Cesium.Matrix4.fromUniformScale(Cesium.defaultValue(this._model.scale,0));
	   Cesium.Matrix4.multiply(matrix, scale, matrix);
	   var rotationX = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(Cesium.defaultValue(this._model.rotation.pitch,0)));
	   var rotationY = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(Cesium.defaultValue(this._model.rotation.heading,0)));
	   var rotationZ = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(Cesium.defaultValue(this._model.rotation.roll,0)));
	   var rotationTranslationX = Cesium.Matrix4.fromRotationTranslation(rotationX);
	   var rotationTranslationY = Cesium.Matrix4.fromRotationTranslation(rotationY);
	   var rotationTranslationZ = Cesium.Matrix4.fromRotationTranslation(rotationZ);
	   Cesium.Matrix4.multiply(matrix, rotationTranslationX, matrix);
	   Cesium.Matrix4.multiply(matrix, rotationTranslationY, matrix);
	   Cesium.Matrix4.multiply(matrix, rotationTranslationZ, matrix);
	   return matrix;
	}
	getCenter(tileset) {
	    var result = {};
	    //记录模型原始的中心点
	    var boundingSphere =tileset.boundingSphere;
	    var position = boundingSphere.center;
	    var catographic = Cesium.Cartographic.fromCartesian(position);
	
	    var height = Number(catographic.height.toFixed(2));
	    var longitude = Number(Cesium.Math.toDegrees(catographic.longitude).toFixed(6));
	    var latitude = Number(Cesium.Math.toDegrees(catographic.latitude).toFixed(6));
	    result = { x: longitude, y: latitude, z: height };
	    //如果tileset自带世界矩阵矩阵，那么计算放置的经纬度和heading
	    if (tileset._root && tileset._root.transform) {
	        var matrix = Cesium.Matrix4.fromArray(tileset._root.transform);
	        var pos = Cesium.Matrix4.getTranslation(matrix, new Cesium.Cartesian3());
	        var wpos = Cesium.Cartographic.fromCartesian(pos);
	        if (Cesium.defined(wpos)) {
	            result.x = Number(Cesium.Math.toDegrees(wpos.longitude).toFixed(6));
	            result.y = Number(Cesium.Math.toDegrees(wpos.latitude).toFixed(6));
	            result.z = Number(wpos.height.toFixed(2));
	
	            //取旋转矩阵
	            var rotmat = Cesium.Matrix4.getMatrix3(matrix, new Cesium.Matrix3());
	            //默认的旋转矩阵
	            var defrotmat = Cesium.Matrix4.getMatrix3(Cesium.Transforms.eastNorthUpToFixedFrame(pos), new Cesium.Matrix3());
	
	            //计算rotmat 的x轴，在defrotmat 上 旋转
	            var xaxis = Cesium.Matrix3.getColumn(defrotmat, 0, new Cesium.Cartesian3());
	            var yaxis = Cesium.Matrix3.getColumn(defrotmat, 1, new Cesium.Cartesian3());
	            var zaxis = Cesium.Matrix3.getColumn(defrotmat, 2, new Cesium.Cartesian3());
	
	            var dir = Cesium.Matrix3.getColumn(rotmat, 0, new Cesium.Cartesian3());
	
	            dir = Cesium.Cartesian3.cross(dir, zaxis, dir);
	            dir = Cesium.Cartesian3.cross(zaxis, dir, dir);
	            dir = Cesium.Cartesian3.normalize(dir, dir);
	
	            var heading = Cesium.Cartesian3.angleBetween(xaxis, dir);
	
	            var ay = Cesium.Cartesian3.angleBetween(yaxis, dir);
	
	            if (ay > Math.PI * 0.5) {
	                heading = 2 * Math.PI - heading;
	            }
	            result.rotation_x = 0;
	            result.rotation_y = 0;
	            result.rotation_z = Number(Cesium.Math.toDegrees(heading).toFixed(1));
	            result.heading = result.rotation_z; //兼容v1老版本
	           // console.log("模型内部世界矩阵:" + JSON.stringify(result));
	        }
	    }
	    return result;
	}
}
export {Tile3d}